#include "BinaryChromosome.h"

BinaryChromosome::BinaryChromosome() : Chromosome()
{
}

BinaryChromosome::BinaryChromosome(int size) : Chromosome()
{
    bitArray = QBitArray(size);
}

BinaryChromosome::BinaryChromosome(const BinaryChromosome &other) : Chromosome(other)
{
    bitArray = QBitArray(other.bitArray);
}

BinaryChromosome::~BinaryChromosome()
{
}

BinaryChromosome& BinaryChromosome::operator=(const BinaryChromosome& other)
{
    this->Chromosome::operator=(other);

    bitArray = other.bitArray;

    return *this;
}

void BinaryChromosome::setRandom()
{
    for(int i=0;i<bitArray.size();++i)
        if(qrand()%2 == 0)
            bitArray.toggleBit(i);
}

void BinaryChromosome::crossOver(const Chromosome& partner)
{
    if(this->size() != partner.size())
        qFatal("Parents chromosomes lenght is different!");

    int crossOverPosition;
    //cross point randomed, greater than 0, smaller than chromosome size
    crossOverPosition = (qrand() % (this->size() -1)) + 1;
    //qDebug() << "mother: " << *this;
    //qDebug() << "father: " << partner;
    //qDebug() << "crossOverPosition: " << crossOverPosition;

    QBitArray mask(this->size());
    mask.fill(true, 0, crossOverPosition);

    this->bitArray &= mask;
    //TODO
    this->bitArray |= static_cast<const BinaryChromosome&>(partner).bitArray & (~mask);

    this->setFitness(0);

    //qDebug() << "child:  " << *this;
}

void BinaryChromosome::mutate(int index)
{
    //qDebug() << "mutationPosition: " << index + 1;
    //qDebug() << "before mutation: " << *this;
    bitArray.toggleBit(index);
    //qDebug() << "after  mutation: " << *this;
}

bool BinaryChromosome::operator==(const Chromosome& other) const
{
    //TODO
    //qDebug() << "operator==";
    return (bitArray == static_cast<const BinaryChromosome&>(other).bitArray);
}

QString BinaryChromosome::toString() const
{
    QString out("");

    for(int i=0;i<bitArray.size();++i)
        out += bitArray.testBit(i) == true ? "1" : "0";

    return out;
}

Chromosome* BinaryChromosome::duplicate() const
{
    return new BinaryChromosome(*this);
}

QVariant BinaryChromosome::at(int index) const
{
    return bitArray.at(index);
}

QVariant BinaryChromosome::data() const
{
    QList<QVariant> list;
    for(int i=0;i<bitArray.size();++i)
        list.append(bitArray.at(i));
    return list;
}

int BinaryChromosome::size() const
{
    return bitArray.size();
}
